package com.portal.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.portal.backend.exception.ResourceNotFoundException;
import com.portal.backend.exception.UnauthorizedException;
import com.portal.backend.mapper.ArticleMapper;
import com.portal.backend.mapper.UserMapper;
import com.portal.backend.mapper.ArticleLikeMapper;
import com.portal.backend.model.Article;
import com.portal.backend.model.User;
import com.portal.backend.model.ArticleLike;
import com.portal.backend.payload.ArticleRequest;
import com.portal.backend.payload.ArticleResponse;
import com.portal.backend.payload.UserSummary;
import com.portal.backend.security.UserPrincipal;
import com.portal.backend.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.List;
import java.util.ArrayList;

@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ArticleLikeMapper articleLikeMapper;

    @Override
    public ArticleResponse createArticle(ArticleRequest articleRequest) {
        UserPrincipal userPrincipal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        User author = userMapper.selectById(userPrincipal.getId());
        if (author == null) throw new ResourceNotFoundException("User", "id", userPrincipal.getId());

        Article article = new Article();
        article.setTitle(articleRequest.getTitle());
        article.setContent(articleRequest.getContent());
        article.setUserId(author.getId());

        articleMapper.insert(article);
        return mapArticleToResponse(article, author);
    }

    @Override
    public ArticleResponse getArticleById(Long id) {
        Article article = articleMapper.selectById(id);
        if (article == null) throw new ResourceNotFoundException("Article", "id", id);
        User author = userMapper.selectById(article.getUserId());
        return mapArticleToResponse(article, author);
    }

    @Override
    public IPage<ArticleResponse> getAllArticles(long current, long size) {
        Page<Article> page = articleMapper.selectPage(new Page<>(current, size), null);
        return page.convert(article -> {
            User author = userMapper.selectById(article.getUserId());
            return mapArticleToResponse(article, author);
        });
    }

    @Override
    public IPage<ArticleResponse> getArticlesByAuthor(Long userId, long current, long size) {
        User author = userMapper.selectById(userId);
        if (author == null) throw new ResourceNotFoundException("User", "id", userId);
        Page<Article> page = articleMapper.selectPage(
                new Page<>(current, size),
                new QueryWrapper<Article>().eq("user_id", userId)
        );
        return page.convert(article -> mapArticleToResponse(article, author));
    }

    @Override
    public ArticleResponse updateArticle(Long id, ArticleRequest articleRequest) {
        Article article = articleMapper.selectById(id);
        if (article == null) throw new ResourceNotFoundException("Article", "id", id);
        UserPrincipal userPrincipal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!article.getUserId().equals(userPrincipal.getId())) {
            throw new UnauthorizedException("You are not authorized to update this article.");
        }
        article.setTitle(articleRequest.getTitle());
        article.setContent(articleRequest.getContent());
        articleMapper.updateById(article);
        User author = userMapper.selectById(article.getUserId());
        return mapArticleToResponse(article, author);
    }

    @Override
    public void deleteArticle(Long id) {
        Article article = articleMapper.selectById(id);
        if (article == null) throw new ResourceNotFoundException("Article", "id", id);
        UserPrincipal userPrincipal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!article.getUserId().equals(userPrincipal.getId())) {
            throw new UnauthorizedException("You are not authorized to delete this article.");
        }
        articleMapper.deleteById(id);
    }

    @Override
    public void likeArticle(Long id) {
        Article article = articleMapper.selectById(id);
        if (article == null) throw new ResourceNotFoundException("Article", "id", id);
        article.setLikeCount(article.getLikeCount() == null ? 1 : article.getLikeCount() + 1);
        articleMapper.updateById(article);
    }

    @Override
    public boolean toggleLike(Long articleId, Long userId) {
        QueryWrapper<ArticleLike> wrapper = new QueryWrapper<>();
        wrapper.eq("article_id", articleId).eq("user_id", userId);
        ArticleLike like = articleLikeMapper.selectOne(wrapper);
        Article article = articleMapper.selectById(articleId);
        if (article == null) throw new ResourceNotFoundException("Article", "id", articleId);
        if (like != null) {
            // 已点赞，取消
            articleLikeMapper.deleteById(like.getId());
            article.setLikeCount(article.getLikeCount() == null ? 0 : article.getLikeCount() - 1);
            articleMapper.updateById(article);
            return false;
        } else {
            // 未点赞，点赞
            ArticleLike newLike = new ArticleLike();
            newLike.setArticleId(articleId);
            newLike.setUserId(userId);
            articleLikeMapper.insert(newLike);
            article.setLikeCount(article.getLikeCount() == null ? 1 : article.getLikeCount() + 1);
            articleMapper.updateById(article);
            return true;
        }
    }

    @Override
    public boolean hasLiked(Long articleId, Long userId) {
        QueryWrapper<ArticleLike> wrapper = new QueryWrapper<>();
        wrapper.eq("article_id", articleId).eq("user_id", userId);
        return articleLikeMapper.selectCount(wrapper) > 0;
    }

    @Override
    public List<UserSummary> getLikeUsers(Long articleId) {
        List<ArticleLike> likes = articleLikeMapper.selectList(
            new QueryWrapper<ArticleLike>().eq("article_id", articleId)
        );
        List<UserSummary> users = new ArrayList<>();
        for (ArticleLike like : likes) {
            User user = userMapper.selectById(like.getUserId());
            if (user != null) {
                users.add(new UserSummary(user.getId(), user.getUsername(), user.getFullName(), user.getAvatar()));
            }
        }
        return users;
    }

    private ArticleResponse mapArticleToResponse(Article article, User author) {
        ArticleResponse response = new ArticleResponse();
        response.setId(article.getId());
        response.setTitle(article.getTitle());
        response.setContent(article.getContent());
        if (author != null) {
            response.setAuthor(new UserSummary(author.getId(), author.getUsername(), author.getFullName(), author.getAvatar()));
        }
        response.setCreatedAt(article.getCreatedAt());
        response.setUpdatedAt(article.getUpdatedAt());
        response.setLikeCount(article.getLikeCount());
        return response;
    }
} 